package com.smf.lsc.security.resource.config;

import javax.servlet.Filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;

import com.smf.lsc.security.converter.MyAccessTokenConverter;

/**
 * 资源配置 
 * Created on 2021/11/19.
 *
 * @author ln
 * @since 1.0
 */
@Configuration
@ComponentScan(basePackages = {"com.smf.lsc.security.*"})
public class ResourceServerConfiguration  {

	/**
	 * 开启spring security注解
	 * @author ln
	 *
	 */
	@Configuration
	@EnableResourceServer
	@EnableGlobalMethodSecurity(prePostEnabled = true)
	@ConditionalOnProperty(prefix = "security.oauth2", name = "enable", havingValue = "true")
	public static class ResourceServerConfig extends ResourceServerConfigurerAdapter{
		
		@Value("${security.oauth2.permis-urls:''}")
	    private String permisUrls;
		
		@Autowired
		private Filter permitAuthenticationFilter;

		@Override
		public void configure(HttpSecurity http) throws Exception {
			
            String[] permisUrl= permisUrls.split(",");
            
			http.csrf().disable()
			.addFilterBefore(permitAuthenticationFilter, AbstractPreAuthenticatedProcessingFilter.class)
			.authorizeRequests()
	        .antMatchers(permisUrl).permitAll()
			.anyRequest().authenticated();
			
//			http.addFilterBefore(permitAuthenticationFilter, OAuth2AuthenticationProcessingFilter.class);
//			http.csrf().disable().authorizeRequests().antMatchers("/**").authenticated()
//	        .antMatchers("/test").permitAll()
//	        .antMatchers(HttpMethod.GET, "/api")
//			// 拦截用户，必须具有所列权限
//			.hasAuthority("ROLE_USER");
		}
		

		@Autowired
		private TokenStore tokenStore;
		
		@Bean(name = "tokenStore")
	    public TokenStore tokenStore() {
	         return new JwtTokenStore(new JwtAccessTokenConverter());
	    }

		@Override
		public void configure(ResourceServerSecurityConfigurer resourceServerSecurityConfigurer) throws Exception {
			resourceServerSecurityConfigurer.tokenStore(tokenStore);
		}

		/**
		 * 自定义token信息转换
		 * 
		 * @return
		 * 
		 *         将token中的扩展信息加入到securityContext中
		 */
		@Bean
		public AccessTokenConverter accessTokenConverter() {
			// return new DefaultAccessTokenConverter();
			return new MyAccessTokenConverter();
		}

		@Bean
		@Primary
		public RemoteTokenServices remoteTokenServices(
				final @Value("${security.oauth2.resource.token-info-uri}") String checkTokenUrl,
				final @Value("${security.oauth2.client.client-id}") String clientId,
				final @Value("${security.oauth2.client.client-secret}") String clientSecret) {
			final RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
			remoteTokenServices.setCheckTokenEndpointUrl(checkTokenUrl + "?name=value");
			remoteTokenServices.setClientId(clientId);
			remoteTokenServices.setClientSecret(clientSecret);
			remoteTokenServices.setAccessTokenConverter(accessTokenConverter());
			return remoteTokenServices;
		}
	    
	}
	
	@Configuration
	@ConditionalOnProperty(prefix = "security.oauth2", name = "enable", havingValue = "false",matchIfMissing = true)
	public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	   
	   @Override
	   protected void configure(HttpSecurity http) throws Exception {
	      http.csrf().disable()
	         .authorizeRequests()
	         .anyRequest().permitAll()
	         .and().logout().permitAll();
	   }
	   
	}
}